/**
 * \file
 *           tlmRmtCfgSrvApp.cpp
 * \brief
 *           Implements tlmRmtCfgSrvApp class for Telematics
 *           this is the derived class from tlmServiceApp clas.
 *           It's the service class for remote configuration 
 *
 * \par Author (last changes):
 *          - Zeng Jie
 *          - BUIC, Continental Automotive Holdings Co., Ltd.
 * \par Project Leader:
 *          -
 * \par Responsible Developer:
 *          - Zeng Jie
 *          - BUIC, Continental Automotive Holdings Co., Ltd.
 * \par Responsible Architect:
 *          - Zhang Fa
 *          - BUIC, Continental Automotive Holdings Co., Ltd.
 *
 * \par Project:
 *      DPCA2
 *
 * \par SW-Component:
 *      Telematics
 *
 * \par SW-Package:
 *      Telematics
 *
 * \par SW-Module:
 *      Telematics Application
 *
 * \par SW-Architecture Specification:
 *      DPCA - TELEMATICS SW DD
 *      05b
 *
 * \par SW-Design Specification:
 *      DPCA - TELEMATICS SW DD
 *      05b
 *
 * \par SW-Test Case Specification:
 *
 * \par CM-Info:
 *
 * \note
 *      This is a note.
 *
 * \bug
 *      - there are no known bugs
 *
 * \par Module-History:
 *
 * \verbatim
 * Date                Author					Reason
 * 10 Dec 2013        Zeng Jie              Initial Creation
 * The latest entry at the head of the history list.
 * \endverbatim
 *
 * \par Copyright Notice:
 * Copyright (C) 2012 Continental Automotive Holdings Co., Ltd.
 * Alle Rechte vorbehalten. All Rights Reserved.\n
 * The reproduction, transmission or use of this document or its contents is
 * not permitted without express written authority.\n
 * Offenders will be liable for damages. All rights, including rights created
 * by patent grant or registration of a utility model or design, are reserved.
 *
 */
#include "stdafx.h"
#include "tlmServiceFactory.h"
#include "tlmRmtCfgSrvApp.h"
//## operation OnReceiveMsg(tlmServiceMsg)
#include "tlmServiceMsg.h"
#include "tlmRmtCfgSrvApp.h"
#include "tlmRmtCfgSrvRpcSyncDesc.h"
#include "tlmRmtCfgSrvRpcAsyncDesc.h"

//## class tlmRmtCfgSrvApp
tlmRmtCfgSrvApp* tlmRmtCfgSrvApp::mpInstance;

/**
* \brief tlmRmtCfgSrvApp: this is constructor of tlmRmtCfgSrvApp class
*
* \note
*
* \param[in]
* - none
*
* \return
* - none
*/
tlmRmtCfgSrvApp::tlmRmtCfgSrvApp() : tlmServiceApp(), ActiveClass(), mAckStatus(TLM_ACK_STATUS_OK), mParaAdmin(),mParaNavi(),mParaWeb(){
}

/**
* \brief ~tlmRmtCfgSrvApp: this is destructor of tlmRmtCfgSrvApp class
*
* \note
*
* \param[in]
* - none
*
* \return
* - none
*/
tlmRmtCfgSrvApp::~tlmRmtCfgSrvApp() {
}

/**
* \brief GetAckStatus: get the ack status which indicates save parameters status
*
* \note
*
* \param[in]
* - none
*
* \return
* - uint8_t : ack status
*
* DesignID: MRN_TLM-SRV_SW_DD_113
*/
uint8_t tlmRmtCfgSrvApp::GetAckStatus() {
    return mAckStatus;
}

/**
* \brief GetInstance: retrieve or create new instace of tlmRmtCfgSrvApp
*
* \note
*
* \param[in]
* - none
*
* \return
* - tlmRmtCfgSrvApp*: pointer to tlmRmtCfgSrvApp instance
*
* DesignID: MRN_TLM-SRV_SW_DD_109
*/
tlmRmtCfgSrvApp* tlmRmtCfgSrvApp::GetInstance() {
    if(mpInstance == NIL)
    {
        mpInstance = new tlmRmtCfgSrvApp;
        LOG_PRINT(DPCA_SYS_CONFIG_INFO,"[CONFIGMENU]:<tlmRmtCfgSrvApp::GetInstance()> get remote configuration service Instance \n");
    
    }
    return mpInstance;
}

/**
* \brief destroyInstance: destroy action when the object is delete.
*
* \note
*
* \param[in]
* - none
*
* \return
* - none
*
*/
void tlmRmtCfgSrvApp::destroyInstance(void)
{
    LOG_PRINT(DPCA_SYS_CONFIG_INFO,"[CONFIGMENU]:<tlmRmtCfgSrvApp::destroyInstance()> destroy the instance\n");
}

/**
* \brief initialize: this function initialization the service app.
*
* \note
*
* \param[in]
* - none
*
* \return
* - none
*
*/
void tlmRmtCfgSrvApp::initialize(void)
{
	LOG_PRINT(DPCA_TELE_MAIN_INFO,"[tlmRmtCfgSrvApp]:tlmRmtCfgSrvApp::initialize\n");
    //TODO:add initialization actions at here
}

/**
 *
 * \brief  This function perform the syncronize call of process handler class.
 *
 * \param p [in] Pointer of the data structure of RPC call
 *
 * \return - none
 */
void tlmRmtCfgSrvApp::__SyncCall(RPC_IOCTL_PTR p) {
    //#[ operation __SyncCall(RPC_IOCTL_PTR)
    tlmRmtCfgSrvRpcSyncDesc desc(p);
    desc.send(p->ac->mExecutionThread);
    //#]
}

/**
 * \brief  This function perform the Asyncronize call of process handler class.
 *
 * TestID: 
 *
 * \param p [in]  Pointer of the data structure of RPC call
 *
 * \return - none
 */
void tlmRmtCfgSrvApp::__AsyncCall(RPC_IOCTL_PTR p) {
    //#[ operation __AsyncCall(RPC_IOCTL_PTR)
    tlmRmtCfgSrvRpcAsyncDesc* pDesc = new tlmRmtCfgSrvRpcAsyncDesc(p);
    pDesc->send(p->ac->mExecutionThread);
    //#]
}




/**
* \brief GetParaAdmin : get the admin parameter object
*
* \note
*
* \param[in]
* - none
*
* \return
* - tlmRmtCfgParaAdmin* : pointer to admin parameter object
*
* DesignID: MRN_TLM-SRV_SW_DD_108
*/
tlmRmtCfgParaAdmin* tlmRmtCfgSrvApp::GetParaAdmin() {
    tlmRmtCfgParaAdmin * pParaAdmin = NIL;

    pParaAdmin = &mParaAdmin;
    return pParaAdmin;
}
/**
* \brief GetParaNavi : get the Navi parameter object
*
* \note
*
* \param[in]
* - none
*
* \return
* - tlmRmtCfgParaNavi* : pointer to Navi parameter object
*
* DesignID: MRN_TLM-SRV_SW_DD_107
*/
tlmRmtCfgParaNavi* tlmRmtCfgSrvApp::GetParaNavi() {
    tlmRmtCfgParaNavi * pParaNavi = NIL;

    pParaNavi = &mParaNavi;
    
    return pParaNavi;
}
/**
* \brief GetParaWeb : get the Web parameter object
*
* \note
*
* \param[in]
* - none
*
* \return
* - tlmRmtCfgParaWeb* : pointer to Web parameter object
*
* DesignID: MRN_TLM-SRV_SW_DD_106
*/
tlmRmtCfgParaWeb* tlmRmtCfgSrvApp::GetParaWeb() {
    tlmRmtCfgParaWeb * pParaWeb= NIL;

    pParaWeb = &mParaWeb;
    
    return pParaWeb;
}

/**
* \brief SaveParameters: Save parameters of remote configuration service
*
* \note
*
* \param[in]
* - none
*
* \return
* - uint8_t: save status
*
* DesignID: MRN_TLM-SRV_SW_DD_112
*/
uint8_t tlmRmtCfgSrvApp::SaveParameters() {
    uint8_t status=TLM_ACK_STATUS_OK;
    status = mParaWeb.Save(); 
    if(status == TLM_ACK_STATUS_OK)
    {  
    	status = mParaNavi.Save(); 
    }  
    
    if(status == TLM_ACK_STATUS_OK)
    {  
    	status = mParaAdmin.Save(); 
    } 
    
    return status;
    //#]
}
/**
* \brief SendMsg: send the messag to server 
*
* \note
*
* \param[in]
* - msg: pointer to message object that include the message which shall be send.
*
* \return
* - none
*
* DesignID: MRN_TLM-SRV_SW_DD_111
*/
void tlmRmtCfgSrvApp::SendMsg(tlmServiceMsg* msg) const{
    if(mMsgHandler!=NIL)
    {
    	mMsgHandler->SendMsg(msg->GetOutMsgPtr(),msg->GetTotalSize());
    }
    //#]
}

/**
* \brief OnReceiveMsg: this function is called when received message
* 
* \note
*
* \param[in]
* - srvMsg: pointere to serviceMsg object which is the received message
*
* \return
* - none
*
* DesignID: MRN_TLM-SRV_SW_DD_110
*/
void tlmRmtCfgSrvApp::OnReceiveMsg(tlmServiceMsg* srvMsg) {
    //#[ operation OnReceiveMsg(tlmServiceMsg)
    s_RPC_IOCTL lRpc;

	/* RPC IOCTL stucture */
	lRpc.ac = this;
	lRpc.dmFuncID = FUNCID_TLM_RMT_CFG_HANDLE_MSG;
	lRpc.lpInBuffer = static_cast<void *>(srvMsg);
	lRpc.lpOutBuffer =  NIL;
	lRpc.nInBufferSize = sizeof(srvMsg);
	lRpc.nOutBufferSize = 0;

	this->AsyncCall(&lRpc);

    
    __OnReceiveMsg(srvMsg);
    //#]
}

/**
* \brief __OnReceiveMsg:This function is the actual handler function to process the message 
*               it shall save the message if it's incoming traffic message
*               parse the data infomation section, and process it. 
* 
* \note
*
* \param[in]
* - none
*
* \return
* - none
*
* DesignID: MRN_TLM-SRV_SW_DD_102
*/
void tlmRmtCfgSrvApp::__OnReceiveMsg(tlmServiceMsg* srvMsg) {
	uint8_t msgType=0;
	BOOL retVal=TRUE;

    //#[ operation __OnReceiveMsg(tlmServiceMsg)
    srvMsg->SaveMsg();
    
    //here can process the message
    retVal = srvMsg->HandleData(); 
	if(retVal)
	{
		srvMsg->GetMsgType(msgType);
		switch(msgType)
		{
    		case TLM_MSG_TYPE_RMT_CFG_PENDING:
            {
    			__OnReceivePendingMsg(srvMsg);
    			break;    
            }
	    	
    		case TLM_MSG_TYPE_RMT_CFG_REQUEST:
            {
    			__OnReceiveReqParaMsg(srvMsg);
    			break; 
            }
	    	
    		case TLM_MSG_TYPE_RMT_CFG_SET_PARA:
            {
    			__OnReceiveSetParaMsg(srvMsg);
    			break;    
            }
	    	
    		default:
            {
    			break;
            }
	    	
		}
	}

	return;
      
    
    
    //#]
}

/**
* \brief __OnReceivePendingMsg: this function is used to process pending(27) message
*                   it create con(29) message, fill it and send it to server
*
* \note
*
* \param[in]
* - srvMsg: pointer to message which should be pending message
*
* \return
* - none
*
* DesignID: MRN_TLM-SRV_SW_DD_103
*/
void tlmRmtCfgSrvApp::__OnReceivePendingMsg(tlmServiceMsg* srvMsg) const{
    //#[ operation __OnReceivePendingMsg(tlmServiceMsg)
    //Received an pending message(mstType:0x27), need send connection message to offboard server.
    
    //SetupHttpConnection();  
    
    tlmServiceMsg* pConMsg=NIL;
    pConMsg = tlmServiceFactory::GetInstance()->CreateSrvMsg(TLM_SRV_TYPE_REMOTE_CONFIG,TLM_MSG_TYPE_RMT_CFG_CONNECT);
    
    if(pConMsg!=NIL)
    {
        pConMsg->Init();
        pConMsg->Fill();
        SendMsg(pConMsg);
    }
    
    //#]
}

/**
* \brief __OnReceiveReqParaMsg: this function is used to process reqPara(28) message
*               it get current configuration if it's requested, then create sendPara(31)
*               message and send it to server
*
* \note
*
* \param[in]
* - srvMsg: pointer to message which should be reqPara message
*
* \return
* - none
*
* DesignID: MRN_TLM-SRV_SW_DD_104
*/
void tlmRmtCfgSrvApp::__OnReceiveReqParaMsg(tlmServiceMsg* srvMsg) {
    //#[ operation __OnReceiveReqParaMsg(tlmServiceMsg)
    //Received an pending message(mstType:0x28), need send parameters message to offboard server.
    tlmRmtCfgParaWeb *pParaWeb = NIL;     
    tlmRmtCfgParaNavi *pParaNavi = NIL;
    tlmRmtCfgParaAdmin *pParaAdmin = NIL; 
    
    //check if the parameters is requested to send
    pParaWeb = srvMsg->GetParaWeb();
    if(pParaWeb!=NIL)
    {
    	mParaWeb.SetRequested(pParaWeb->IsRequested());  
    	pParaWeb->ClearRequested();
    } 
    
    //check if the parameters is requested to send
    pParaNavi = srvMsg->GetParaNavi();
    if(pParaNavi!=NIL)
    {
    	mParaNavi.SetRequested(pParaNavi->IsRequested());
    	pParaNavi->ClearRequested();
    } 
    
    //check if the parameters is requested to send
    pParaAdmin = srvMsg->GetParaAdmin();
    if(pParaAdmin!=NIL)
    {   
    	//set the current para flag
    	mParaAdmin.SetRequested(pParaAdmin->IsRequested()); 
    	
    	//clear the component in message.
    	pParaAdmin->ClearRequested();
    } 
                                   
                              
    //SetupHttpConnection();  
    
    tlmServiceMsg* pSendParaMsg=NIL;
    pSendParaMsg = tlmServiceFactory::GetInstance()->CreateSrvMsg(TLM_SRV_TYPE_REMOTE_CONFIG,TLM_MSG_TYPE_RMT_CFG_SEND_PARA);
    
    if(pSendParaMsg!=NIL)
    {    
    	pSendParaMsg->SetItsService(this);
        pSendParaMsg->Init();
        pSendParaMsg->Fill();
        SendMsg(pSendParaMsg);
    }         
    
    //After send the message, shall clear the requested flag.
    mParaWeb.ClearRequested();
    mParaNavi.ClearRequested();
    mParaAdmin.ClearRequested();
    
    //#]
}

/**
* \brief __OnReceiveSetParaMsg: this function is used to process setPara(30) message
*           it update current configuration, and save it into NVM
*
* \note
*
* \param[in]
* - srvMsg: pointer to message which should be setPara message
*
* \return
* - none
*
* DesignID: MRN_TLM-SRV_SW_DD_105
*/
void tlmRmtCfgSrvApp::__OnReceiveSetParaMsg(tlmServiceMsg* srvMsg) {
    //#[ operation __OnReceiveSetParaMsg(tlmServiceMsg)
    //Received an set para message(mstType:0x30), need update the configuration parameters.  
    
    //the parameters has been parsed in srvMsg, we just need to update it. 
    
    tlmRmtCfgParaWeb *pParaWeb = NIL;     
    tlmRmtCfgParaNavi *pParaNavi = NIL;
    tlmRmtCfgParaAdmin *pParaAdmin = NIL;
    
    //update the web parameters
    pParaWeb = srvMsg->GetParaWeb();
    if(pParaWeb!=NIL)
    {
    	mParaWeb.Update(pParaWeb);
    } 
    
    //update the navi parameters  
    pParaNavi = srvMsg->GetParaNavi();
    if(pParaNavi!=NIL)
    {
    	mParaNavi.Update(pParaNavi);
    }  
    
    //update the Admin parameters
    pParaAdmin = srvMsg->GetParaAdmin();
    if(pParaAdmin!=NIL)
    {
    	mParaAdmin.Update(pParaAdmin);
    }       
    
    mAckStatus=SaveParameters();  
    //After update message, we shall send Ack message to offboard server.  
    
    //SetupHttpConnection();  
    
    tlmServiceMsg* pAckMsg=NIL;
    pAckMsg = tlmServiceFactory::GetInstance()->CreateSrvMsg(TLM_SRV_TYPE_REMOTE_CONFIG,TLM_MSG_TYPE_RMT_CFG_ACK);
    
    if(pAckMsg!=NIL)
    {    
    	pAckMsg->SetItsService(this);
        pAckMsg->Init();
        pAckMsg->Fill();
        SendMsg(pAckMsg);
    }

	
     
    
    
    //#]
}
